/**
 * ReqJS是专门负责处理请求的接口，这里会封装一些常用的请求方法
 */
import axios, { AxiosRequestConfig } from 'axios'
import { message } from 'antd'
import qs from 'qs'
// import {promiseConfig} from '@/config/env-config'
import { getCookie } from './cookie'

export const SYMOBOL = {
	// 请求的错误信息
	request_error: Symbol('request_error'),
	// 请求源信息
	request_origin: Symbol('request_origin'),
}

// const codeMessage = {
//   200: '服务器成功返回请求的数据。',
//   201: '新建或修改数据成功。',
//   202: '一个请求已经进入后台排队（异步任务）。',
//   204: '删除数据成功。',
//   400: '发出的请求有错误，服务器没有进行新建或修改数据的操作。',
//   401: '用户没有权限（令牌、用户名、密码错误）。',
//   403: '用户得到授权，但是访问是被禁止的。',
//   404: '发出的请求针对的是不存在的记录，服务器没有进行操作。',
//   406: '请求的格式不可得。',
//   410: '请求的资源被永久删除，且不会再得到的。',
//   422: '当创建一个对象时，发生一个验证错误。',
//   500: '服务器发生错误，请检查服务器。',
//   502: '网关错误。',
//   503: '服务不可用，服务器暂时过载或维护。',
//   504: '网关超时。',
// };
// 基本请求配置属性
export const baseOptions = {
	withCredentials: true,
	timeout: 30000,
	validateStatus(status: number) {
		return status >= 200 && status < 300
	},
}

/**
 * @description: 基本请求
 * @param {AxiosRequestConfig} options axios请求配置
 * @return {Object<any>} 请求结果
 */
export async function request(options: AxiosRequestConfig) {
	const { headers } = options
	const currentMerchantId: any = getCookie('orgId')
	return axios({
		...options,
		headers: {
			currentMerchantId,
			...headers,
			'current-path': window.location.href,
		},
	})
		.then((res) => {
			const response = res.data
			response[SYMOBOL.request_error] = null
			response[SYMOBOL.request_origin] = res
			if (!res.data.success) {
				const msg = res.data.msg || res.data.message
				message.error(msg)
			}
			return response

		})
		.catch((err) => {
			const response: any = {}
			// const config = err.config || {}
			let errTips = '请求服务器异常'
			if (err.toString() === 'Cancel') {
				errTips = '请求被取消'
				message.info(errTips)
			} else {
				// errTips += `\n  --请求地址: ${config?.url}`;
				errTips += `\n (错误信息: ${err})`
				message.error(errTips)
			}
			response[SYMOBOL.request_error] = err
			response[SYMOBOL.request_origin] = err
			return response
		})
}

/**
 * @description: 包裹一个请求变为promise请求
 * @param {fn} 要包裹的函数
 * @return {fn} 包裹后的函数
 */
function pwrapper(
	fn: (
		url: string,
		params?: any,
		options?: AxiosRequestConfig,
	) => Promise<any>,
) {
	return (url: string, params?: any, options?: AxiosRequestConfig) => {
		// const apiPrefix = `/api/promise`;
		// const apiPrefix = `/api/promise/${promiseConfig[ENV]}`;
		const startWith = url.startsWith('/')
		return fn(`${startWith ? '' : '/'}${url}`, params, options)
	}
}

/**
 * @description: 基础get请求
 * @param {string} url 请求url
 * @param {Object<any>} params 请求参数
 * @param {Object<any>} options 请求配置（详细查看 axios）
 * @return {Object<any>} 返回请求结果
 */
export function get(url: string, params?: any, options?: AxiosRequestConfig) {
	return request({
		...baseOptions,
		url,
		params,
		...options,
	})
}
export const pget = pwrapper(get)

/**
 * @description: 基础post请求
 * @param {string} url 请求url
 * @param {Object<any>} params 请求参数
 * @param {Object<any>} options 请求配置（详细查看 axios）
 * @return {Object<any>} 返回请求结果
 */
export function post(url: string, params?: any, options?: any) {
	return request({
		url,
		...baseOptions,
		method: 'post',
		headers: {
			Accept: 'application/json',
			'Content-Type': 'application/x-www-form-urlencoded',
		},
		data: qs.stringify(params),
		...options,
	})
}
export const ppost = pwrapper(post)

/**
 * @description: 基础json体的post请求
 * @param {string} url 请求地址
 * @param {Object<any>} params 请求参数
 * @param {Object<any>} options 请求配置（详细查看 axios）
 * @return {Object<any>} 返回结果
 */
export function postJson(url: string, params?: any, options?: any) {
	return request({
		url,
		...baseOptions,
		method: 'post',
		headers: {
			Accept: 'application/json',
			'Content-Type': 'application/json',
		},
		data: JSON.stringify(params),
		...options,
	})
}
export const ppostJson = pwrapper(postJson)

/**
 * @description: 基础binary stream体的post请求
 * @param {string} url 请求地址
 * @param {Object<any>} params 请求参数
 * @param {Object<any>} options 请求配置（详细查看 axios）
 * @return {Object<any>} 返回结果
 */
export function postFileByStream(url: any, file?: any, options?: any) {
	return request({
		url,
		...baseOptions,
		method: 'post',
		headers: {
			Accept: 'application/json',
			'Content-Type': 'binary/octet-stream',
		},
		data: file,
		...options,
	})
}
export const ppostFileByStream = pwrapper(postFileByStream)

/**
 * @description: 基于FormData的post请求
 * @param {string} url 请求地址
 * @param {Object} params 请求参数
 * @param {Object} options 请求配置
 * @return {Object<any>} 返回结果
 */
export function postFileByFormData(
	url: string,
	params: Object = {},
	options: Object = {},
) {
	return request({
		url,
		...baseOptions,
		method: 'post',
		headers: {
			Accept: 'application/json',
			'Content-Type': 'multipart/form-data',
		},
		data: params,
		...options,
	})
}
export const ppostFileByFormData = pwrapper(postFileByFormData)

export const { CancelToken } = axios

export default {
	request,
	get,
	post,
	postJson,
	postFileByStream,
	postFileByFormData,
	pget,
	ppost,
	ppostJson,
	ppostFileByStream,
	ppostFileByFormData,
}
